﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FlexFlow.Base.Interface;
using FlexFlow.Model;
using MongoDB.Driver;

namespace FlexFlow.DataProvider.MongoDB
{
    /// <summary>
    /// 基于MongoDb的工作流表单模板实体工厂实现
    /// </summary>
    public class MongoDbFormTemplateProvider : MongoDBPhysicalModelProvider<FormTemplate>, IFormTemplateProvider
    {
        /// <summary>
        /// 使用默认设置创建工作流表单模板
        /// </summary>
        /// <returns>
        /// 创建的工作流表单模板
        /// </returns>
        public override FormTemplate Create()
        {
            return new Model.FormTemplate()
            {
                State = FormTemplateState.Created,
                Message = "等待编译"
            };
        }
        /// <summary>
        /// 判断指定的文件Id的文件是否已经作为模板使用
        /// </summary>
        /// <param name="fileId">
        /// 要判断的文件Id
        /// </param>
        /// <returns>
        /// 一个值，表示文件是否已经作为模板使用
        /// </returns>
        public bool CheckFileInstalled(Guid fileId)
        {
            var col = GetCollection();
            FilterDefinition<FormTemplate> filter = (FilterDefinition<FormTemplate>)(m => m.PhysicalFileId == fileId);
            return col.FirstOrDefault(filter) != null;
        }

        /// <summary>
        /// 取得一个未编译的模板信息并更新其编译信息为 Compiling
        /// </summary>
        /// <returns>
        /// 取得的模板信息
        /// </returns>
        public FormTemplate GetAndSetState()
        {
            var col = GetCollection();
            FilterDefinition<FormTemplate> filter = (FilterDefinition<FormTemplate>)(m => m.State == FormTemplateState.Created);
            FormTemplate temp = col.FirstOrDefault(filter);

            if (temp == null)
                return null;

            temp.State = FormTemplateState.Compiling;

            if (!UpdateState(temp.Identity, FormTemplateState.Compiling, "正在编译"))
            {
                return null;
            }

            return temp;
        }

        /// <summary>
        /// 更新指定模板的状态及消息
        /// </summary>
        /// <param name="state">
        /// 要更新的状态
        /// </param>
        /// <param name="Message">
        /// 状态消息
        /// </param>
        /// <returns>
        /// 更新是否成功
        /// </returns>
        public bool UpdateState(Guid id, FormTemplateState state, string message)
        {
            var updef = BuildUpdateDef(m => m.State, state);
            updef = BuildUpdateDef(m => m.Message, message, updef);
            return Update(id, updef);
        }
        /// <summary>
        /// 查询名称中包含指定字符的表单模板集合
        /// </summary>
        /// <param name="nameLike">
        /// 要查询的表单模板名称
        /// </param>
        /// <param name="limit">
        /// 限制数量
        /// </param>
        /// <param name="skip">
        /// 返回数据的起始位置
        /// </param>
        /// <param name="isAll">
        /// 一个值，表示返回的结果是所有的表单模板还是已安装的表单模板
        /// </param>
        /// <returns>
        /// 查询结果
        /// </returns>
        public List<FormTemplate> QueryByName(string nameLike,int skip = 0, int limit = 5, bool isAll = false)
        {
            var col = GetCollection();
            FilterDefinition<FormTemplate> filterDef = null;
            if (!isAll)
	        {
               filterDef = (FilterDefinition<FormTemplate>)(m=>m.State == FormTemplateState.Compiled);
            }
            FindOptions<FormTemplate> findOpt = new FindOptions<FormTemplate>()
            {
                Skip = skip,
                Limit = limit
            };
            return col.QueryByName(nameLike, findOpt, filterDef);
        }
        /// <summary>
        /// 取得指定的文件安装后的表单模板
        /// </summary>
        /// <param name="fileId">
        /// 要取得的表单模板的文件ID
        /// </param>
        /// <returns>
        /// 取得的表单模板
        /// </returns>
        public FormTemplate GetByFileId(Guid fileId)
        {
            FilterDefinition<FormTemplate> filterDef = (FilterDefinition<FormTemplate>)(m => m.PhysicalFileId == fileId);
            var col = GetCollection();
            return col.FirstOrDefault(filterDef);
        }
    }
}
